using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace ApplicationLibrary.ExtendedControls
{
    public class LookUpCombo : ComboBox
    {
        private int countItem = 0;
        private int descIndent = 0;
        protected SortedList<string, string> SL = null;
        private Control descriptionControl = null;

        public int MaxCodeLength = 0;
        public int MaxDescLength = 0;

        // constructor
        public LookUpCombo()
        {
            // set draw mode to owner draw
            this.DrawMode = DrawMode.OwnerDrawFixed;
            SL = new SortedList<string, string>();
        }

        public Control DescriptionControl { set { descriptionControl = value; } }

        public void ClearElement()
        {
            SL.Clear();
        }

        public void AddElement(string code, string desc)
        {
            SL.Add(code, desc);
            this.Items.Add(new LookUpComboItem(code, desc));
            if (code.Length > MaxCodeLength) MaxCodeLength = code.Length;
            if (desc.Length > MaxDescLength) MaxDescLength = desc.Length;
        }

        protected override void OnTextChanged(EventArgs e)
        {
            if (descriptionControl != null && this.Text != "" && SL.ContainsKey(this.Text))
                descriptionControl.Text = SL[this.Text];

            base.OnTextChanged(e);
        }

        protected override void OnSelectedItemChanged(EventArgs e)
        {
            if (descriptionControl != null && this.Text != "" && SL.ContainsKey(this.Text))
                descriptionControl.Text = SL[this.Text];

            base.OnSelectedItemChanged(e);
        }

        protected override void OnSelectedIndexChanged(EventArgs e)
        {
            if (descriptionControl != null && this.Text != "" && SL.ContainsKey(this.Text))
                descriptionControl.Text = SL[this.Text];

            base.OnSelectedIndexChanged(e);
        }

        public void AddElements(Dictionary<string, string> sl)
        {
            if (SL.Count == 0)
            {
                this.Items.Clear();
                foreach (KeyValuePair<string, string> kvp in sl)
                {
                    SL.Add(kvp.Key, kvp.Value);
                    this.Items.Add(new LookUpComboItem(kvp.Key, kvp.Value));
                }
            }
        }

        // customized drawing process
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            if (countItem != this.Items.Count)
                descIndent = CalculateIndent(e);

            // draw background & focus rect
            e.DrawBackground();
            e.DrawFocusRectangle();

            // check if it is an item from the Items collection
            if (e.Index < 0)

                // not an item, draw the text (indented)
                e.Graphics.DrawString(this.Text, e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left, e.Bounds.Top);

            else
            {
                // check if item is an ImageComboItem
                if (this.Items[e.Index].GetType() == typeof(LookUpComboItem) && (e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit)
                {
                    // get item to draw
                    LookUpComboItem item = (LookUpComboItem)this.Items[e.Index];

                    // get forecolor & font

                    e.Graphics.DrawString(item.Code, e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left, e.Bounds.Top);
                    e.Graphics.DrawLine(new Pen(Color.Gray), e.Bounds.Left + descIndent, e.Bounds.Top, e.Bounds.Left + descIndent, e.Bounds.Bottom);
                    e.Graphics.DrawString(item.Descrription, e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left + descIndent + 4, e.Bounds.Top);
                }
                else

                    // it is not an ImageComboItem, draw it
                    e.Graphics.DrawString(this.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left, e.Bounds.Top);
            }

            base.OnDrawItem(e);
        }

        private int CalculateIndent(DrawItemEventArgs e)
        {
            int indent = 0;
            for (int t = 0; t < this.Items.Count; t++)
            {
                int strlen = (int)e.Graphics.MeasureString(this.Items[t].ToString(), e.Font).Width;
                if (strlen > indent) indent = strlen;
            }
            return indent;
        }
    }
}